#include <LitStdAfx.h>
#include <LitExceptions.h>

namespace Lit
{
	Exception::Exception( ExceptionType type, const std::string &_msg, const std::string &func_, int _line, const std::string &_file ) 
	{
		mMessage=_msg;
		mLine=_line; mFile=_file; mFunc= func_; mType= type; 
		_buildFull();
	}
	Exception::Exception( const Exception& rk )
	{
		mMessage = rk.mMessage;
		mLine = rk.mLine;mFile = rk.mFile;mFunc = rk.mFunc;mType = rk.mType;mFull=rk.mFull;
	}
	Exception::~Exception( ){}

	std::string Exception::location() const{ return String(" in function ")(mFunc)(" at line ")(mLine)(" in file ")(mFile).str(); }
	std::string Exception::error() const{ return String("Exception(")(std::string(trExceptionType(mType)))("): ")(mMessage).str(); }
		
	void Exception::_buildFull(){ mFull = String()("Exception(")(std::string(trExceptionType(mType)))(")\r\n--------------------\r\n")(location())("\r\n\t")(mMessage).str(); }

	const std::string &Exception::full() const{ return mFull; }

	const char * Exception::what() const{ return mFull.c_str(); }

	ExceptionType Exception::type() const{ return mType; }
	int Exception::line() const{ return mLine; }
	const std::string& Exception::file() const{ return mFile; }
	const std::string& Exception::message() const{ return mMessage; }
	const std::string& Exception::function() const{ return mFunc; }

	RuntimeError::RuntimeError( ExceptionType type, const std::string &_msg, const std::string &func_, int _line, const std::string &_file ) : Exception( type, _msg, func_, _line, _file ), std::runtime_error( mFull ){}
	RuntimeError::RuntimeError( const std::string &_msg, const std::string &func_, int _line, const std::string &_file ) : Exception( EXC_RUNTIME_ERROR, _msg, func_, _line, _file ), std::runtime_error( mFull ){}
	RuntimeError::RuntimeError( const RuntimeError & rk  ) : Exception( rk ), std::runtime_error( rk ){}
	RuntimeError::~RuntimeError( ){}

	LogicError::LogicError( ExceptionType type, const std::string &_msg, const std::string &func_, int _line, const std::string &_file ) : Exception( type, _msg, func_, _line, _file ), logic_error( mFull ){}
	LogicError::LogicError( const std::string &_msg, const std::string &func_, int _line, const std::string &_file ) : Exception( EXC_LOGIC_ERROR, _msg, func_, _line, _file ), logic_error( mFull ){}
	LogicError::LogicError( const LogicError & rk ) : Exception(rk), std::logic_error(rk){}
	LogicError::~LogicError( ){}

	NullPointer::NullPointer( const std::string &msg, const std::string &func_, int _line, const std::string &_file ) : RuntimeError( EXC_ITEM_MISSING, ("invalid pointer"+(msg.empty()?String(""):(", "+msg))).str(), func_, _line, _file ){}

	CastError::CastError( const std::string &varname, const std::string &from, const std::string &to, const std::string &func_, int _line, const std::string &_file ) : LogicError( EXC_CAST_ERROR, ("cannot convert"+(varname.empty()?String(""):(" variable '"+varname+"'"))+" from "+from+" to "+to).str(), func_, _line, _file ){}

	ImplementationMissing::ImplementationMissing( const std::string &func_name, const std::string &func_, int _line, const std::string &_file ) : LogicError( EXC_ITEM_MISSING, ("Function '"+func_name+"' not yet implemented !"), func_, _line, _file ){}

	IOError::IOError( const std::string &filename, const std::string& desc, const std::string &func_, int _line, const std::string &_file ) : RuntimeError( EXC_IO_ERROR, ("io_error '"+filename+"': "+desc), func_, _line, _file ){}

	InitialisationError::InitialisationError( const std::string &msg, const std::string &func_, int _line, const std::string &_file ) : LogicError( EXC_INIT_ERROR, ("Cannot initialise lit engine"+(msg.empty()?String(""):(":\r\n--------------------------------------------\r\n\t"+msg))).str(), func_, _line, _file ){}
	ShutdownError::ShutdownError( const std::string &msg, const std::string &func_, int _line, const std::string &_file ) : LogicError( EXC_SHUTDOWN_ERROR, ("Cannot shutdown lit engine"+(msg.empty()?String(""):(":\r\n--------------------------------------------\r\n\t"+msg))).str(), func_, _line, _file ){}

	InvalidPath::InvalidPath( const std::string &path, bool directory, const std::string &func_, int _line, const std::string &_file ) : RuntimeError( EXC_ITEM_MISSING, ("invalid path '"+path+"' for '"+(directory?"directory":"filestream")+"'"), func_, _line, _file ){}

	InvalidParameter::InvalidParameter( const std::string &param, const std::string &reason, const std::string &func_, int _line, const std::string &_file ) 	: LogicError( EXC_ITEM_MISSING, ("invalid parameter '"+param+"', "+reason), func_, _line, _file ){}
	MissingParameter::MissingParameter( const std::string &param, const std::string &func_, int _line, const std::string &_file ) : LogicError( EXC_ITEM_MISSING, ("missing parameter '"+param+"'"), func_, _line, _file ){}

	ItemMissing::ItemMissing( const std::string &iitem, const std::string &item_mgr_name, const std::string &func_, int _line, const std::string &_file ) : LogicError( EXC_ITEM_MISSING, item+" missing in Manager['"+item_mgr_name+"']", func_, _line, _file ), item(iitem){}
	ItemDuplicate::ItemDuplicate( const std::string &iitem, const std::string &item_mgr_name, const std::string &func_, int _line, const std::string &_file ) 	: LogicError( EXC_ITEM_DUPLICATE, item+" already found in Manager['"+item_mgr_name+"']", func_, _line, _file ), item(iitem){}

	FileMissing::FileMissing( const std::string &ffilename, const std::string &func, int line, const std::string &file )	: RuntimeError( EXC_FILE_MISSING, "Missing file '"+filename+"'", func, line, file ), filename( ffilename ){}
	FileDuplicate::FileDuplicate( const std::string &ffilename, const std::string &func, int line, const std::string &file ): RuntimeError( EXC_FILE_DUPLICATE, "File '"+filename+"' already exists, duplicates not allowed", func, line, file ), filename( ffilename ){}
	
	ModuleException::ModuleException( const std::string &module, const std::string& error, const std::string &_func , int _line, const std::string &_file ) : RuntimeError( EXC_COMPONENT_ERROR, ("Module '"+module+"' caused the following exception:\n"+error), _func, _line, _file ), moduleName( module ){}
	
	ConsoleError::ConsoleError( const std::string &desc, const std::string &func, size_t line, const std::string& file ) : RuntimeError( EXC_CONSOLE_ERROR, String(desc+" "+(!func.empty()?("in function '"+func+"' "):" ") +"at line "+Ogre::StringConverter::toString( line )+" in file "+file), func, line, file ){}
	ConsoleTerminateError::ConsoleTerminateError( const std::string &msg, const std::string &func, size_t line, const std::string& file ) : RuntimeError( "/quit "+msg, func, line, file ){}
};